package util

import (
	"encoding/json"
	"log"
	"os"
	"strconv"
	"strings"
)

const (
	// 配置文件加载方式
	loadTypeDefault = "DEFAULT" // 默认
	loadTypeConfig  = "CONFIG"  // 配置文件
	loadTypeCommand = "COMMAND" // 命令行

	// 配置文件路径
	configPath = "./config.json"
)

// 服务配置
type ServerConfig struct {
	Port        int    `json:"port"`        // 端口，默认3000
	ContextPath string `json:"contextPath"` // 服务上下文路径，默认/
	LoadType    string `json:"loadType"`    // 配置文件加载方式，无需传入，加载方式标记
}

// 企业微信配置
type WxWorkConfig struct {
	Url            string `json:"url"`            // 请求接口地址
	Url2           string `json:"url2"`           // 新接口
	MerchantId     string `json:"merchantId"`     // 商户编号
	MpAppId        string `json:"mpAppId"`        // 公众号APPID
	AppRedirectUrl string `json:"appRedirectUrl"` // 业务App重定向地址
	BaseInfoApi    string `json:"baseInfoApi"`    // 基础信息接口
	Whitelist      string `json:"whitelist"`      // 白名单工号
}

// 企业微信用户信息接口
type WxUserConfig struct {
	Url     string `json:"url"`     // 请求接口地址
	AgentId string `json:"agentId"` // 应用ID
	Type    string `json:"type"`    // dev or prod
}

// 配置信息
type Config struct {
	Server ServerConfig `json:"server"` // 服务配置
	WxWork WxWorkConfig `json:"wxWork"` // 企业微信配置
	WxUser WxUserConfig `json:"wxUser"` // 企业微信用户信息接口
}

// 配置信息
var config *Config

func init() {
	config = loadConfig()
}

func GetConfig() Config {
	return *config
}

// 加载配置信息
func loadConfig() *Config {
	conf := Config{Server: ServerConfig{
		Port:        3000,
		ContextPath: "/",
		LoadType:    loadTypeDefault,
	}}

	// 检查配置文件是否存在，若存在则加载
	_, err := os.Stat(configPath)
	if err == nil {
		file, _ := os.Open(configPath)
		defer file.Close()
		decoder := json.NewDecoder(file)
		err = decoder.Decode(&conf)
		if err != nil {
			conf.Server.LoadType = loadTypeDefault
			log.Println("Load config error, use default config.", err)
		} else {
			conf.Server.LoadType = loadTypeConfig
		}
	}
	return loadCommandArgs(&conf)
}

// 从命令行覆盖配置
func loadCommandArgs(conf *Config) *Config {
	args := os.Args

	if len(args) >= 2 {
		var err error
		conf.Server.LoadType = loadTypeCommand
		if conf.Server.Port, err = strconv.Atoi(args[1]); err != nil {
			log.Fatalln("Illegal port")
		}
	}
	if len(args) >= 3 {
		conf.Server.ContextPath = strings.TrimSpace(args[2])
		if len(conf.Server.ContextPath) > 0 && !strings.HasPrefix(conf.Server.ContextPath, "/") {
			log.Fatalln("Illegal context path, it should like '/financial'")
		}
	}
	return conf
}
